﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Web;
using System.Windows.Forms;
using System.Collections;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.XPath;
using TMXmlRpcLib;

namespace tm_servermanager
{

    public partial class Form1 : Form
    {
        //public XmlRpcClient[] client = new XmlRpcClient[15];
        public Server[] tmServer = new Server[16];    
        private int ActiveServerPage = 0;
        public int serverCount = 0;
        public long tickCounter;
        public long updateCounter;
        bool appStart = true;
        //public TmColor tmColor = new TmColor();
     
        //Delegaatti
        public delegate void UpdateServer_Delegate(int server);
        
        public Form1()
        {
            InitializeComponent();
            Form2 form2 = new Form2();
            form2.Show();
            form2.Refresh();
            tickCounter = EpochNow();
            updateCounter = EpochNow();
            LoadXml();


            int i = 0;

            if (serverCount != 0)
            {
                for (i = 0; i < serverCount; i++)
                {
                    tmServer[i].Chat = new ArrayList();
                    tmServer[i].Players = new ArrayList();
                    tmServer[i].NetworkInfo = new NetworkInfo();
                    tmServer[i].ServerInfo = new ServerInfo();
                    tmServer[i].ServerController = new ServerController();
                    tmServer[i].ServerController.LastAnswer = 0;
                    tmServer[i].Client = new XmlRpcClient(tmServer[i].Address, tmServer[i].Port);
                    int step = (int)((i / serverCount) * 100);
                    connectClient(i);
                }

            }
            form2.Hide();

        }

        
        private void LoadXml()
        {
            XmlReader xmlreader = new XmlTextReader("servers.xml");
            XmlDocument doc = new XmlDocument();
            xmlreader.Read();
            doc.Load(xmlreader);
            XmlElement root = doc.DocumentElement;
            XmlNodeList servers = root.SelectNodes("/settings/server");
            int i = 0;
            foreach (XmlNode info in servers)
            {
                foreach (XmlNode data in info)
                {

                    switch (data.Name)
                    {
                        case "name":
                            tmServer[i].Name = data.InnerText;
                            break;
                        case "address":
                            tmServer[i].Address = data.InnerText;
                            break;
                        case "port":
                            tmServer[i].Port = int.Parse(data.InnerText);
                            break;
                        case "login":
                            tmServer[i].Login = data.InnerText;
                            break;
                        case "password":
                            tmServer[i].Password = data.InnerText;
                            break;
                    }
                }
                textBox2.Text = i+":"+textBox2.Text + ":" + tmServer[i].Port+"\r\n";
                i++;
            }

            serverCount = i;
            

           // updateTab1Servers();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
          
       }

        public void getServerinfos(int i)
        {
            if (tmServer[i].Connected == true)
            {

                GbxCall call = tmServer[i].Client.Request("GetServerOptions", new object[] { (int)1 });


                double ladderRankMin = (double)((Hashtable)call.Params[0])["LadderServerLimitMin"];
                double ladderRankMax = (double)((Hashtable)call.Params[0])["LadderServerLimitMax"];
                int players = (int)((Hashtable)call.Params[0])["CurrentMaxPlayers"];
                tmServer[i].Name = ((Hashtable)call.Params[0])["Name"].ToString();

                tmServer[i].ServerInfo.MaxPlayers = (int)(players);
                tmServer[i].ServerInfo.LadderRankMax = (int)(ladderRankMax) / 1000;
                tmServer[i].ServerInfo.LadderRankMin = (int)(ladderRankMin) / 1000;
                GbxCall call2 = tmServer[i].Client.Request("GetPlayerList", new object[] { (int)64, (int)0, (int)1 });
                tmServer[i].Players.Clear();
                foreach (Hashtable t in ((ArrayList)call2.Params[0])) {
                    tmServer[i].Players.Add(t);
                }          

                tmServer[i].Chat.Clear();
                GbxCall call3 = tmServer[i].Client.Request("GetChatLines", new object[] { (int)64, (int)0, (int)1 });
                foreach (String t in ((ArrayList)call3.Params[0]))
                {
                    tmServer[i].Chat.Add(t);
                }

                GbxCall call4 = tmServer[i].Client.Request("GetCurrentChallengeInfo", new object[] { });
                tmServer[i].ServerInfo.currentMap = ((Hashtable)call4.Params[0])["Name"].ToString();

                GbxCall call5 = tmServer[i].Client.Request("GetNetworkStats", new object[] { (int)64, (int)0, (int)1 });
                tmServer[i].NetworkInfo.Uptime = (int)((Hashtable)call5.Params[0])["Uptime"];
                tmServer[i].NetworkInfo.MeanConnectionTime = (int)((Hashtable)call5.Params[0])["MeanConnectionTime"];
                tmServer[i].NetworkInfo.MeanNbrPlayer = (int)((Hashtable)call5.Params[0])["MeanNbrPlayer"];
                tmServer[i].NetworkInfo.NbrConnection = (int)((Hashtable)call5.Params[0])["NbrConnection"];

            }

        }
        public void getPlayersOnServer(int i)
        {
            
            GbxCall call = tmServer[i].Client.Request("GetPlayerList", new object[] { (int)64, (int)0, (int)1 });
            tmServer[i].Players.Clear();
            foreach (Hashtable t in ((ArrayList)call.Params[0]))
            {
                tmServer[i].Players.Add(t);
            }
            UpdateServerPlayers(i);
        }
               
        public void client_EventOnDisconnectCallback(object o, Exception ex)
        {

            XmlRpcClient test = o as XmlRpcClient;
            
            string ip = test.IP;
            int port = test.Port;
            int i = 0;
            
            foreach (Server serv in tmServer) {
                if (serv.Address == ip)
                {
                    if (serv.Port == port)
                    {
                        tmServer[i].Connected = false;
                        tmServer[i].ServerController.Connected = false;
                        break;
                    }

                }
                i++;
            }
           
           tmServer[i].Client.EventGbxCallback -= new GbxCallbackHandler(Client_EventGbxCallback);
           tmServer[i].Client.EventOnDisconnectCallback -= new OnDisconnectHandler(client_EventOnDisconnectCallback);
             //MessageBox.Show("Disconnected from:"+tmServer[i].Name+"\nException: "+ex.Message);
            //client.Connect();
        }
        public void Client_EventGbxCallback(object sender, GbxCallbackEventArgs e)
        {

            XmlRpcClient test = sender as XmlRpcClient;

            String ip = test.IP;
            int port = test.Port;
            int i = 0;
            int currentServer = -1;

            foreach (Server serv in tmServer)
            {
                if (serv.Address == ip)
                {
                    if (serv.Port == port)
                    {
                        currentServer = i;
                        break;
                    }

                }
                i++;
            }
                     
            if (e.Response.MethodName == "TrackMania.PlayerConnect")
            {
                UpdateServer_Delegate Runme = new UpdateServer_Delegate(getPlayersOnServer);
                Invoke(Runme, currentServer);  
            }

            if (e.Response.MethodName == "TrackMania.PlayerDisconnect")
            {
                UpdateServer_Delegate Runme = new UpdateServer_Delegate(getPlayersOnServer);
                Invoke(Runme, currentServer);  
            }

            if (e.Response.MethodName == "TrackMania.BeginChallenge")
            {
                UpdateServer_Delegate Runme = new UpdateServer_Delegate(getCurrentMapOnServer);
                Invoke(Runme, currentServer);
            }

            if (e.Response.MethodName == "TrackMania.PlayerChat")
            {
                String Chat = "";
                String Login = (String)e.Response.Params[1];
                String Text = (String)e.Response.Params[2];
                if (Text[0] == '/') return;
                
                foreach (Hashtable player in tmServer[currentServer].Players)
                {
                    if (player["Login"].ToString() == Login)
                    {
                        Chat += "$ff0[$<" + player["NickName"].ToString() + "$>] ";
                        break;
                    } 
                }
                Chat += Text;
                tmServer[currentServer].Chat.Add(Chat);
                tmServer[currentServer].ServerController.LastAnswer = EpochNow();

                UpdateServer_Delegate Runme = new UpdateServer_Delegate(UpdateServerChatLines);
                Invoke(Runme, currentServer);              

            }

            if (e.Response.MethodName == "TrackMania.Echo")
            {
                string data = e.Response.Params[0].ToString();
                string source = e.Response.Params[1].ToString();

                if (source == "tmServerManager|manialive|pong")
                {
                  tmServer[currentServer].ServerController.Name = "manialive";
                  tmServer[currentServer].ServerController.LastAnswer = EpochNow();
                }
                
                if (source == "tmServerManager|manialive|hello")
                {
                tmServer[currentServer].ServerController.Name = "manialive";
                tmServer[currentServer].ServerController.Version = data;
                tmServer[currentServer].ServerController.LastAnswer = EpochNow();
                }
               
            }
        }

        public void getCurrentMapOnServer(int server)
        {
            GbxCall call4 = tmServer[server].Client.Request("GetCurrentChallengeInfo", new object[] { });
            tmServer[server].ServerInfo.currentMap = ((Hashtable)call4.Params[0])["Name"].ToString();
            UpdateCurrentMap(server);
        }


        public void UpdateCurrentMap(int page)
        {
            if (page == -1) return;
            Control[] cht = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "CurrentChallenge", true);
            RichTextBox box = (RichTextBox)cht[0];
            String output = tmServer[page].ServerInfo.currentMap;
            box.Rtf = parseTmText(output);
      }

        public void UpdateServerChatLines(int page)
        {
            if (page == -1) return;
            if (tmServer[page].Chat.Count == 0) return;
            Control[] cht = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "ChatBox", true);
            RichTextBox chat = (RichTextBox)cht[0];
            String output = "";
            foreach (String chatline in tmServer[page].Chat)
            {
                output +=  "\\b0\\i0"+ chatline + "\\cf1\\par";
            }

            chat.Rtf = parseTmText(output);
            
            chat.SelectionStart = chat.Text.Length-1;
            chat.ScrollToCaret();
        }

        private void manageServersToolStripMenuItem_Click(object sender, EventArgs e)
        {
        
        }

        private void sendUpdateRequests()
        {
            for (int i = 0; i < serverCount; i++)
            {
                if (tmServer[i].Connected)
                {
                    tmServer[i].Client.Request("Echo", new object[] { "tmServerManager|main", "ping" });
                }
                if (tmServer[i].Client != null && tmServer[i].Connected == false)
                {
                    connectClient(i);
                }
            }

        }


        public Boolean connectClient(int i)
        {
            int status = tmServer[i].Client.Connect();
            if (status == 1)
            {
                tmServer[i].Connected = false;
                
                return false;
            }
            if (status == 2)
            {
                tmServer[i].Connected = false;
                tmServer[i].Error = true;
                
                return false;
            }

            tmServer[i].Connected = true;
            tmServer[i].Error = false;

            GbxCall call = tmServer[i].Client.Request("Authenticate", new object[] { tmServer[i].Login, tmServer[i].Password });
            if (call.Error)
            {
                tmServer[i].Connected = false;
                tmServer[i].Error = true;
                tmServer[i].Client.Disconnect();
               
                return false;
            }

            
            tmServer[i].Client.EnableCallbacks(true);
            tmServer[i].Client.EventGbxCallback += new GbxCallbackHandler(Client_EventGbxCallback);
            tmServer[i].Client.EventOnDisconnectCallback += new OnDisconnectHandler(client_EventOnDisconnectCallback);
            tmServer[i].Client.Request("Echo", new object[] { "tmServerManager|main", "ping" });
            tmServer[i].ServerController.LastAnswer = 0;
            getServerinfos(i);
            return true;
        }

        private void updateGeneralServers()
        {
            int lbl = 0;
            int pbox = 0;

            for(int i = 0; i < 16; i++) {
                pbox++;
                lbl++;
                Control[] cnt1 = Controls.Find("pictureBox" + (pbox),true);
                PictureBox pb1 = (PictureBox)cnt1[0];
                if (tmServer[i].Connected) pb1.Image = getmyIcon("online"); else pb1.Image = getmyIcon("offline");
                if (tmServer[i].Error) pb1.Image = getmyIcon("error");
                if (tmServer[i].Name == null) pb1.Image = getmyIcon("config");
                pbox++; // add one to picturebox;
                Control[] cnt2 = Controls.Find("pictureBox" + (pbox), true);
                PictureBox pb2 = (PictureBox)cnt2[0];
                if (tmServer[i].ServerController.Connected) pb2.Image = getmyIcon("online"); else pb2.Image = getmyIcon("offline");
                if (tmServer[i].ServerController.Name == null) pb2.Image = getmyIcon("config");
                
                Control[] cnt3 = Controls.Find("label" + (lbl), true);
                Label lab1 = (Label)cnt3[0];
                if (tmServer[i].Connected == true)
                {
                    if (tmServer[i].Players != null)
                        lab1.Text = "Players: " + tmServer[i].Players.Count + "/" + tmServer[i].ServerInfo.MaxPlayers;
                }
                else
                {
                    lab1.Text = "";
                }
                
                lbl++; // add one to label
                
                Control[] cnt4 = Controls.Find("label" + (lbl), true);
                Label lab2 = (Label)cnt4[0];
                if (tmServer[i].Connected == true)
                {
                    lab2.Text = "Server Rank: " + tmServer[i].ServerInfo.LadderRankMin + "-" + tmServer[i].ServerInfo.LadderRankMax + "k LP";
                }
                else
                {
                    lab2.Text = "";
                }
                Control[] cnt5 = Controls.Find("richTextBox" + (i+1), true);
                RichTextBox rtb1 = (RichTextBox)cnt5[0];
                rtb1.Rtf = parseTmText(tmServer[i].Name);
            }
       }

        private Image getmyIcon(string state) {
            if (state == "online") return Image.FromFile("images/online.png");
            if (state == "offline") return Image.FromFile("images/offline.png");
            if (state == "error") return Image.FromFile("images/error.png");
            if (state == "config") return Image.FromFile("images/config.png");
            return Image.FromFile("images/working.png");

        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            if (appStart && updateCounter + 1 <= EpochNow())
            {
            appStart = false;
            updateGeneralServers();
            return;
            }
            if (updateCounter + 10 <= EpochNow())
            {
                sendUpdateRequests();
                updateGeneralServers();
                updateCounter = EpochNow();
            }
            
            for (int i = 0; i <= serverCount; i++)
            {
                if (tmServer[i].Connected)
                {
                    //MessageBox.Show("" + (EpochNow() - tmServer[i].ServerController.LastAnswer));
                    if (EpochNow() - tmServer[i].ServerController.LastAnswer <= 20 )
                    {
                        tmServer[i].ServerController.Connected = true;
                    }
                    else
                    {
                        tmServer[i].ServerController.Connected = false;
                    }
                }
                else
                {
                    tmServer[i].ServerController.Connected = false;
                }
            }
        }


        private long EpochNow()
        {
            return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }

        private void tabPage1_Click(object sender, EventArgs e)
        {

        }

        private void menuStrip1_LayoutCompleted(object sender, EventArgs e)
        {
            
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            //textBox2.Text = (richTextBox1.Rtf.ToString());
        }

        private void pictureBox19_Click(object sender, EventArgs e)
        {

        }

        private void label19_Click(object sender, EventArgs e)
        {

        }

        private void label20_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox20_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox29_Click(object sender, EventArgs e)
        {

        }

        private void label29_Click(object sender, EventArgs e)
        {

        }

        private void label30_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox30_Click(object sender, EventArgs e)
        {

        }


        private void UpdateServerPlayers(int page)
        {
            if (page == -1) return;
            if (tmServer[page].Connected == false) return;
            Control[] plrs = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "Players", true);
            RichTextBox players = (RichTextBox)plrs[0];
            String output = "";
            foreach (Hashtable player in tmServer[page].Players)
            {
                output += "$000[" + player["Login"].ToString() + "] " + player["NickName"].ToString() + "\\b0\\i0\\par";
            }
            players.Rtf = parseTmText(output);
        }

        private void UpdateServerStatisticsInfo(int page)
        {
            if (tmServer[page].Connected == false) return;
            TimeSpan t;
            Control[] cntr = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "Uptime", true);
            Label lbl = (Label)cntr[0];
            t = TimeSpan.FromSeconds(tmServer[page].NetworkInfo.Uptime);
            String output = "Uptime: " + string.Format("{0:D}days {1:D}h:{2:D2}m:{3:D2}s",
                        t.Days,
                        t.Hours,
                        t.Minutes,
                        t.Seconds);
            lbl.Text = output;

            cntr = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "MeanConnectionTime", true);
            lbl = (Label)cntr[0];
            t = TimeSpan.FromSeconds(tmServer[page].NetworkInfo.MeanConnectionTime);
            output = "MeanConnectionTime: " + string.Format("{0:D}h:{1:D2}m:{2:D2}s",
                        t.Hours,
                        t.Minutes,
                        t.Seconds);
            
            lbl.Text = output;

            cntr = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "MeanNbrPlayer", true);
            lbl = (Label)cntr[0];
            output = "MeanNbrPlayer: " + tmServer[page].NetworkInfo.MeanNbrPlayer;
            lbl.Text = output;

            cntr = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "NbrConnection", true);
            lbl = (Label)cntr[0];
            output = "Total Connections: " + tmServer[page].NetworkInfo.NbrConnection;
            lbl.Text = output;
        
        }
        private void UpdateServerName(int page)
        {
            Control[] nme = tabControl1.TabPages[page + 1].Controls.Find("Server" + (page + 1) + "Name", true);
            RichTextBox name = (RichTextBox)nme[0];
            name.Rtf = parseTmText(tmServer[page].Name);
        }
        
        private void UpdateServerPage(int page)
        {
            if (page == -1) return;
            if (tmServer[page].Connected == false) return;
            UpdateServerName(page);
            UpdateServerStatisticsInfo(page);
            UpdateServerPlayers(page);
            UpdateServerChatLines(page);
            UpdateCurrentMap(page);
        }

        public String parseTmText(String tmText)
        {
            if (tmText == null) return "";
            ArrayList colorTable = new ArrayList();
            ArrayList textTable = new ArrayList();


            String ret = "{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}}";


            String[] tmSplitText = tmText.Split('$');
            if (tmSplitText.Length == 1)
            {
                ret += "\\viewkind4\\uc1\\pard\\lang11\\f0\\fs22";
                ret += tmSplitText[0];
                ret += "";
                return ret;
            }
            else
            {
                int x = 0;
                colorTable.Add(ParseColor("ff0"));
                foreach (String data in tmSplitText)
                {
                    x++;
                    String newdata = data;
                    bool bold = false;
                    bool italic = false;
                    bool isColor = true;
                    bool isLink = false;
                    bool invalidTag = false;

                    Hashtable textAndcolor = new Hashtable();
                    if (data.Length == 0) continue;
                    string d = "" + data[0];

                    switch (d.ToLower())
                    {
                        case "h":
                            newdata = data.Substring(1);
                            isLink = true;
                            isColor = false;
                            break;
                        case "i":
                            if (italic == false)
                            {
                                newdata = "\\i " + data.Substring(1);
                                italic = !italic;
                            }
                            else
                            {
                                newdata = "\\i0" + data.Substring(1);
                                italic = !italic;
                            }
                            isColor = false;
                            break;
                        case "o":
                            if (bold == false)
                            {
                                newdata = "\\b " + data.Substring(1);
                                bold = true;
                            }
                            else
                            {
                                newdata = "\\b0 " + data.Substring(1);
                                bold = false;
                            }
                            isColor = false;
                            break;
                        case "w":
                            if (bold == false)
                            {
                                newdata = "\\b " + data.Substring(1);
                                bold = true;
                            }
                            else
                            {
                                newdata = "\\b0 " + data.Substring(1);
                                bold = false;
                            }
                            isColor = false;
                            break;
                        case "s":
                            newdata = data.Substring(1);
                            isColor = false;
                            break;
                        case "t":
                            newdata = data.Substring(1);
                            isColor = false;
                            break;
                        case "n":
                            newdata = data.Substring(1);
                            isColor = false;
                            break;
                        case "m":
                            newdata = data.Substring(1);
                            isColor = false;
                            break;
                        case "l":
                            isColor = false;
                            isLink = true;
                            break;
                        case "g":
                            newdata = data.Substring(1);
                            isColor = false;
                            break;
                        case "z":
                            isColor = true;
                            bold = false;
                            italic = false;
                            newdata = "ff0\\i0\\b0" + data.Substring(1);
                            break;
                        default:
                            Regex test = new Regex("([0-9a-f])");
                            if (test.IsMatch(d.ToLower()))
                            {
                                isColor = true;
                            }
                            else
                            {
                                invalidTag = true;
                                bold = false;
                                italic = false;
                            }
                            break;

                    }

                    if (invalidTag)
                    {
                        colorTable.Add(ParseColor("ff0"));
                        int count = colorTable.Count;
                        textAndcolor.Add("color", count);
                        textAndcolor.Add("text", "\\i0\\b0"+data.Substring(1));
                        textTable.Add(textAndcolor);
                    }
                    else
                    {

                        if (!isLink)
                        {

                            if (isColor)
                            {
                                int test = x;
                                colorTable.Add(ParseColor(newdata.Substring(0, 3)));
                                int count = colorTable.Count;
                                textAndcolor.Add("color", count);
                                textAndcolor.Add("text", newdata.Substring(3));
                                textTable.Add(textAndcolor);
                            }
                            else
                            {
                                textAndcolor.Add("color", -1);
                                textAndcolor.Add("text", newdata);
                                textTable.Add(textAndcolor);
                            }

                        }
                        else
                        {
                            if (newdata.Length < 1) continue; // invalid data
                            Regex reg = new Regex("(\\[.*\\])");
                            String text = reg.Match(newdata).Value;
                            if (text.Length == 0) continue;  // invalid rexep
                            newdata = newdata.Replace(text, "");
                            if (newdata.Length == 0) continue;  // invalid rexep
                            textAndcolor.Add("color", -1);
                            textAndcolor.Add("text", newdata.Substring(1));
                            textTable.Add(textAndcolor);
                        }
                    } 
                }

                // Generate Colortable;
                ret += "{\\colortbl;";
                for (int i = 0; i < colorTable.Count; i++)
                {
                    ret += colorTable[i];
                }
                ret += "}";

                // generate Text
                ret += "\\viewkind4\\uc1\\pard\\lang11\\f1\\fs22";

                for (int i = 0; i < textTable.Count; i++)
                {

                    int color = (int)((Hashtable)textTable[i])["color"];
                    if (color != -1) ret += "\\cf" + color + " ";

                    String str = ((Hashtable)textTable[i])["text"].ToString();

                    for (int u = 0; u < str.Length; u++)
                    {
                        char uni = str[u];
                        if ((int)uni > 127)
                        {
                            ret += "\\u" + string.Format("{0}", (Int32)uni) + "_";
                        }
                        else
                        {
                            ret += "" + str[u];
                        }
                    }
                }

                ret += "";
               
            }
            return ret;
        }

        public String ParseColor(String Color)
        {
            Regex reg = new Regex("[0-9a-f]");

            if (reg.IsMatch("" + Color[0]) && reg.IsMatch("" + Color[1]) && reg.IsMatch("" + Color[2]))
            {
                String red = "" + Color[0] + Color[0];
                String green = "" + Color[1] + Color[1];
                String blue = "" + Color[2] + Color[2];
                int re, gr, bl;
                re = Convert.ToInt16(red, (int)16);
                gr = Convert.ToInt16(green, (int)16);
                bl = Convert.ToInt16(blue, (int)16);
                String ret = "\\red" + re + "\\green" + gr + "\\blue" + bl + ";";
                return ret;
            }
            else
            {
                String ret = "\\red" + 255 + "\\green" + 255 + "\\blue" + 0 + ";";
                return ret;
            }
            
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            ActiveServerPage = tabControl1.SelectedIndex-1;
            UpdateServerPage(ActiveServerPage);
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
          
        }
        
        private void SendChat(int server, TextBox Chat)
        {
            if (tmServer[server].Connected)
            {
                GbxCall call = tmServer[server].Client.Request("ChatSendServerMessage", new object[] { "$f00ServerManager$fff> " + Chat.Text });
            }
            Chat.Text = "";

        }

        #region All servers SendChat here
        private void Server1chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(0, Server1chatsend);
            }
        }

        private void Server2SendChat_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(1, Server2chatsend);
            }
        }

        private void Server3chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(2, Server3chatsend);
            }
        }

        private void Server4chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(3, Server4chatsend);
            }
        }

        private void Server5chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(4, Server5chatsend);
            }
        }

        private void Server6chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(5, Server6chatsend);
            }
        }

        private void Server7chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(6, Server6chatsend);
            }
        }

        private void Server8chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(7, Server8chatsend);
            }
        }

        private void Server9chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(8, Server9chatsend);
            }
        }

        private void Server10chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(9, Server10chatsend);
            }
        }

        private void Server11chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(10, Server11chatsend);
            }
        }

        private void Server12chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(11, Server12chatsend);
            }
        }

        private void Server13sendchat_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(12, Server13chatsend);
            }
        }

        private void Server14chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(13, Server14chatsend);
            }
        }

        private void Server15chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(14, Server15chatsend);
            }
        }

        private void Server16chatsend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendChat(15, Server16chatsend);
            }
        }
        #endregion

        private void tabPage4_Click(object sender, EventArgs e)
        {

        }

        private void tabPage7_Click(object sender, EventArgs e)
        {

        }
    }

    public struct Server
    {
        public String Address;
        public int Port;
        public String Name;
        public String Login;
        public String Password;
        public Boolean Connected;
        public Boolean Error;
        public XmlRpcClient Client;
        public ArrayList Chat;
        public ArrayList Players;
        public ServerInfo ServerInfo;
        public NetworkInfo NetworkInfo;
        public ServerController ServerController;
    }

    public struct ServerInfo {
        public int MaxPlayers;
        public int NumberPlayers;
        public int LadderRankMax;
        public int LadderRankMin;
        public String currentMap;
    }


    public struct NetworkInfo
    {
       public int Uptime;
       public int NbrConnection;
       public int MeanConnectionTime;
       public int MeanNbrPlayer;        
    }

    public struct ServerController
    {
        public String Name;
        public String Version;
        public long LastAnswer;
        public Boolean Connected;
        public int Memoryusage;

    }
}
